<?php

namespace App\Http\Controllers;

use App\Models\Building;
use App\Models\Dorm;
use App\Models\DormType;
use App\Presenters\DormPresenter;
use Illuminate\Http\Request;
use Prettus\Validator\Contracts\ValidatorInterface;
use Prettus\Validator\Exceptions\ValidatorException;
use App\Http\Requests\DormCreateRequest;
use App\Http\Requests\DormUpdateRequest;
use App\Repositories\DormRepository;
use App\Models\Company;
use App\Models\DormRatingMain;
use App\Models\MeterType;
use App\Models\DormMeterRecord;

/**
 * Class DormsController.
 *
 * @package namespace App\Http\Controllers;
 */
class DormsController extends Controller
{
    /**
     * @var DormRepository
     */
    protected $repository;



    /**
     * DormsController constructor.
     *
     * @param DormRepository $repository
     * @param DormValidator $validator
     */
    public function __construct(DormRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $this->repository->pushCriteria(app('Prettus\Repository\Criteria\RequestCriteria'));

        if (request()->has('limit')) {
            $this->repository->setPresenter(DormPresenter::class);
            $dorms = $this->repository->withCount('staffs')->paginate(request()->get('limit', 20));
        } else {
            $dorms = $this->repository->all(['id', 'building_id', 'code']);
            if (request()->has('period_id')) {
                foreach ($dorms as $dorm) {
                    if (request()->get('for') == 'recording') {
                        //给h5抄表系统用
                        $meters = $dorm->activeMeters()->with('meter_type:id,name,max_consumption,can_reset,reset_limit')->orderBy('meter_type_id')->get(['id', 'meter_type_id', 'last_reading', 'last_reading_date', 'reset_limit']);
                        $records = DormMeterRecord::where('dorm_id', $dorm->id)->where('period_id', request()->get('period_id'))->get(['id', 'dorm_meter_id', 'prev_meter_reading', 'prev_reading_date', 'meter_reading', 'meter_reading_date']);
                        foreach ($meters as $meter) {
                            $record = $records->where('dorm_meter_id', $meter->id)->first();
                            if ($record) {
                                $meter->last_reading = doubleval($record->prev_meter_reading);
                                $meter->last_reading_date = $record->prev_reading_date;
                            }
                        }
                        $dorm->meters = $meters;
                        $dorm->records = $records;
                    } else {
                        //给宿舍评分h5系统用
                        $rating = DormRatingMain::where('dorm_id', $dorm->id)->where('period_id', request()->get('period_id'))->first();
                        if ($rating) {
                            $dorm->rating = $rating->get_score;
                        } else {
                            $dorm->rating = 0;
                        }
                    }
                }
            }
        }

        if (request()->wantsJson()) {

            return response()->json([
                'data' => $dorms,
            ]);
        }
        \request()->flash();
        $buildings = Building::all()->pluck('name', 'id');
        $dormTypes = DormType::all()->pluck('name', 'id');
        return view('dorms.index', compact('dorms', 'buildings', 'dormTypes'));
    }

    /**
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function create()
    {
        $buildings = Building::all();
        $dormTypes = DormType::all();
        $companies = Company::all()->pluck('name', 'id');
        return view('dorms.create', compact('buildings', 'dormTypes', 'companies'));
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  DormCreateRequest $request
     *
     * @return \Illuminate\Http\Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function store(DormCreateRequest $request)
    {
        try {

            $dorm = $this->repository->create($request->all());

            $response = [
                'message' => 'Dorm created.',
                'data'    => $dorm->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {
            if ($request->wantsJson()) {
                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }

    /**
     * Display the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $dorm = $this->repository->find($id);
        if (request()->wantsJson()) {

            return response()->json([
                'data' => $dorm,
            ]);
        }

        return view('dorms.show', compact('dorm'));
    }


    /**
     * Show the form for editing the specified resource.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    {
        $dorm = $this->repository->find($id);
        $buildings = Building::all()->pluck('name', 'id');
        $dormTypes = DormType::all()->pluck('name', 'id');
        $companies = Company::all()->pluck('name', 'id');
        $user = auth()->user();
        return view('dorms.edit', compact('dorm', 'buildings', 'dormTypes', 'companies', 'user'));
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  DormUpdateRequest $request
     * @param  string            $id
     *
     * @return Response
     *
     * @throws \Prettus\Validator\Exceptions\ValidatorException
     */
    public function update(DormUpdateRequest $request, $id)
    {
        try {
            //            $this->validator->with($request->all())->passesOrFail(ValidatorInterface::RULE_UPDATE);
            $dorm = $this->repository->update($request->all(), $id);

            $response = [
                'message' => 'Dorm updated.',
                'data'    => $dorm->toArray(),
            ];

            if ($request->wantsJson()) {

                return response()->json($response);
            }

            return redirect()->back()->with('message', $response['message']);
        } catch (ValidatorException $e) {

            if ($request->wantsJson()) {

                return response()->json([
                    'error'   => true,
                    'message' => $e->getMessageBag()
                ]);
            }

            return redirect()->back()->withErrors($e->getMessageBag())->withInput();
        }
    }


    /**
     * Remove the specified resource from storage.
     *
     * @param  int $id
     *
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $deleted = $this->repository->delete($id);

        if (request()->wantsJson()) {

            return response()->json([
                'message' => 'Dorm deleted.',
                'deleted' => $deleted,
            ]);
        }

        return redirect()->back()->with('message', 'Dorm deleted.');
    }

    public function orderSort()
    {
        $id = \request()->get('building_id');
        if ($id) {
            $dorms = Dorm::where('building_id', $id)->orderBy('record_order')->orderBy('code')->get();
        } else {
            $dorms = Dorm::orderBy('record_order')->orderBy('code')->get();
        }

        return view('dorms.sort', compact('dorms'));
    }

    public function orderSave(Request $request)
    {
        try {
            \DB::beginTransaction();
            $order = $request->get('order');
            foreach ($order as $o => $id) {
                $dorm = Dorm::find($id);
                $dorm->record_order = $o + 1;
                $dorm->save();
            }
            \DB::commit();
            if ($request->wantsJson()) {
                return response()->json([
                    'message' => 'Dorm record order saved.',
                    'saved' => true,
                ]);
            }
            return redirect()->back()->with('message', 'Dorm record order saved.');
        } catch (\Exception $exception) {
            \DB::rollBack();
            if ($request->wantsJson()) {
                return response()->json([
                    'error' => true,
                    'message' => 'Dorm record order saved failed:' . $exception->getMessage(),
                ]);
            }
            return redirect()->back()->withErrors($exception->getMessage());
        }
    }

    public function getDormsByBuilding()
    {
        $dorms = Dorm::where('building_id', request()->get('building_id'))->orderBy('record_order')->orderBy('code')->get();
        return response()->json($dorms);
    }
}
